package cn.stylefeng.guns.core.util;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import org.apache.commons.lang3.StringUtils;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.HashMap;
import java.util.Map;

/**
 * @Data:2021/2/2 15:11
 * @Author:WZ
 */
public class QRCodeUtil2 {


    private static final int QRCOLOR = 0xFF000000; // 二维码颜色 默认是黑色
    private static final int BGWHITE = 0xFFFFFFFF; // 背景颜色

    private static final int WIDTH = 290; // 二维码宽
    private static final int HEIGHT = 290; // 二维码高

    private static final int WORDHEIGHT = 345; // 加文字二维码高

    public static BitMatrix generateQRCodeStream(String content, HttpServletResponse response) {
        //给相应添加头部信息，主要告诉浏览器返回的是图片流
        response.setHeader("Cache-Control", "no-store");
        // 不设置缓存
        response.setHeader("Pragma", "no-cache");
        response.setDateHeader("Expires", 0);
        response.setContentType("image/png");
        //设置图片的文字编码以及内边框
        Map<EncodeHintType, Object> hints = new HashMap<>();
        //编码
        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
        //边框距
        hints.put(EncodeHintType.MARGIN, 0);
        BitMatrix bitMatrix;
        try {
            //参数分别为：编码内容、编码类型、图片宽度、图片高度，设置参数
            bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, 300, 300,hints);
        }catch(WriterException e) {
            e.printStackTrace();
            return null;
        }
        return bitMatrix;

    }

    /**
     * 设置 Graphics2D 属性  （抗锯齿）
     * @param graphics2D
     */
    private static void setGraphics2D(Graphics2D graphics2D){
        graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        graphics2D.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_DEFAULT);
        Stroke s = new BasicStroke(1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER);
        graphics2D.setStroke(s);
    }


    /**
     * 把带logo的二维码下面加上文字
     * @param image
     * @param words
     * @return
     */
    public static BufferedImage insertWords(BufferedImage image,String words){
        // 新的图片，把带logo的二维码下面加上文字
        if (StringUtils.isNotEmpty(words)) {

            //创建一个带透明色的BufferedImage对象
            BufferedImage outImage = new BufferedImage(WIDTH, WORDHEIGHT, BufferedImage.TYPE_INT_ARGB);
            Graphics2D outg = outImage.createGraphics();
            setGraphics2D(outg);

            // 画二维码到新的面板
            outg.drawImage(image, 0, 0, image.getWidth(), image.getHeight(), null);
            // 画文字到新的面板
            Color color=new Color(0,0,0);
            outg.setColor(color);
            // 字体、字型、字号
            if(words != null && words.length() > 8) {
                outg.setFont(new Font("微软雅黑", Font.PLAIN, 25));
            } else {
                outg.setFont(new Font("微软雅黑", Font.PLAIN, 30));
            }

            //文字长度
            int strWidth = outg.getFontMetrics().stringWidth(words);
            //总长度减去文字长度的一半  （居中显示）
            int wordStartX=(WIDTH - strWidth) / 2;
            //height + (outImage.getHeight() - height) / 2 + 12
            int wordStartY=HEIGHT+30;
            // 画文字
            outg.drawString(words, wordStartX, wordStartY);
            outg.dispose();
            outImage.flush();
            return outImage;
        }
        return null;
    }


    /**
     * @description 生成带logo的二维码图片 二维码下面带文字
     * @param logoFile loge图片的路径
     * @param bgFile 背景图片的路径
     * @param qrUrl 二维码内容
     * @param words 二维码下面的文字
     */
    public static void drawLogoQRCode(File logoFile,String qrUrl, String words,
                                      HttpServletRequest request,
                                      HttpServletResponse response) {
        try {
            MultiFormatWriter multiFormatWriter = new MultiFormatWriter();
            //设置图片的文字编码以及内边框
            Map<EncodeHintType, Object> hints = new HashMap<>();
            //编码
            hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
            //边框距
            hints.put(EncodeHintType.MARGIN, 0);
            // 参数顺序分别为：编码内容，编码类型，生成图片宽度，生成图片高度，设置参数
            BitMatrix bm = multiFormatWriter.encode(qrUrl, BarcodeFormat.QR_CODE, WIDTH, HEIGHT, hints);
            BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);

            // 开始利用二维码数据创建Bitmap图片，分别设为黑（0xFFFFFFFF）白（0xFF000000）两色
            for (int x = 0; x < WIDTH; x++) {
                for (int y = 0; y < HEIGHT; y++) {
                    image.setRGB(x, y, bm.get(x, y) ? QRCOLOR : BGWHITE);
                }
            }

            //把logo画到二维码上面
            if (logoFile != null && logoFile.exists()) {
                // 构建绘图对象
                Graphics2D g = image.createGraphics();
                setGraphics2D(g);
                // 读取Logo图片
                BufferedImage logo = ImageIO.read(logoFile);
                // 开始绘制logo图片 等比缩放：（width * 2 / 10 height * 2 / 10）不需缩放直接使用图片宽高
                //width * 2 / 5 height * 2 / 5  logo绘制在中心点位置
                g.drawImage(logo, WIDTH * 2 / 5, HEIGHT * 2 / 5, logo.getWidth(), logo.getHeight(), null);
                g.dispose();
                logo.flush();
            }
            // 新的图片，把带logo的二维码下面加上文字
//            image=insertWords(image,words);
            image.flush();
            ImageIO.write(image, "png", response.getOutputStream());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /*public static void main(String[] args) {
        //logo
        File logoFile = new File("https://wz-picgo.oss-cn-beijing.aliyuncs.com/img/20200330105527.png");
        //背景图片
        File bgFile = new File("https://wz-picgo.oss-cn-beijing.aliyuncs.com/img/20200330105527.png");
        //生成图片
        File qrCodeFile = new File("D:\\dd");
        //二维码内容
        String url = "https://w.url.cn/s/AYmfAV3";
        //二维码下面的文字
        String words = "PSD000001";
        drawLogoQRCode(logoFile,bgFile, url, words);
    }*/

}
